package com.api.user.controller;
import com.api.base.config.auth.JwtTokenUtil;
import com.api.base.model.SysRole;
import com.api.base.model.User;
import com.api.base.service.UserService;
import com.api.common.EmailUtil;
import com.api.core.config.AuthUser;
import com.api.core.controller.Ctrl;
import com.api.core.response.Result;
import com.api.core.response.ResultGenerator;
import com.api.user.config.SubscribeList;
import com.api.user.enums.IdentificationStatusEnums;
import com.api.user.model.*;
import com.api.user.service.UserInfoService;
import com.api.user.vo.SubscribeVo;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import com.api.core.annotation.PowerEnable;
import io.swagger.annotations.*;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
* Created by wanghuiwen on 2021/03/17.
*/
@PowerEnable(name = "UserInfo",url = "/user/info")
@Api(value = "UserInfo", tags = {"UserInfo"})
@RestController
@RequestMapping("/user/info")
public class UserInfoController extends Ctrl{
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private SubscribeList subscribeList;
    @Resource
    private UserService userService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;



    @ApiOperation(value = "UserInfo添加", tags = {"UserInfo"}, notes = "UserInfo添加")
    @PostMapping(value="/register",name="UserInfo添加")
    public Result add(@ApiParam RegisterInput registerInput) {

        return  userInfoService.register(registerInput);
    }



    @ApiOperation(value = "第三方登陆", tags = {"User"}, notes = "第三方登陆")
    @PostMapping(value="/third/login",name="第三方登陆")
    public Result ThirdLogin(@RequestParam String loginType,
                             @RequestParam String token,
                             @RequestParam String email,
                             @RequestParam String name) {
        User user =null;
        if(loginType.equals("google")){
            user= userService.findBy("googleToken",token);
        }
        if(loginType.equals("facebook")){
            user= userService.findBy("facebookToken",token);
        }
        Map<String, Object> res = new HashMap<>();
        if(user!=null){
            String jwtToken = jwtTokenUtil.generateToken(user.getLoginName(),user.getType());
            List<String> roles =  userService.getRole(user.getId()).stream()
                    .map(SysRole::getDescription).distinct()
                    .collect(Collectors.toList());
            res.put("menu",roles);
            res.put("token", jwtToken);
            Map<String,Object> info = userService.info(user.getId());
            res.put("info",info);
            return ResultGenerator.genSuccessResult(res);
        }else {
            RegisterInput registerInput = new RegisterInput();
            registerInput.setEmail(email);
            registerInput.setLoginName(email);
            registerInput.setFullName(name);
            registerInput.setPassword(token);
            registerInput.setRegisterType(loginType);
            registerInput.setUserType(2);
            registerInput.setVerificationCode("9876");
            if(loginType.equals("google")){
                registerInput.setGoogleToken(token);
            }
            if(loginType.equals("facebook")){
                registerInput.setFacebookToken(token);
            }
            return  userInfoService.register(registerInput);
        }
    }


    @ApiOperation(value = "修改用户信息", tags = {"UserInfo"}, notes = "修改用户信息")
    @PostMapping(value="/update",name="修改用户信息")
    public Result update(@ApiParam UserInfoUpdate userInfo) {

        return  userInfoService.updateUserInfo(userInfo);
    }

    @ApiOperation(value = "UserInfo详细信息", tags = {"UserInfo"}, notes = "UserInfo详细信息")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId",required=true, value = "userId", dataType = "Long", paramType = "query")
    })
    @PostMapping(value="/detail",name="UserInfo详细信息")
    public Result detail(@RequestParam Long userId) {
        Map<String,Object> userInfo = userInfoService.detail(userId);
        return ResultGenerator.genSuccessResult(userInfo);
    }

    @ApiOperation(value = "UserInfo列表信息", tags = {"UserInfo"}, notes = "UserInfo列表信息")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "phoneNumber", value = "手机号码", dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "examine", value = "审核状态", dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "fullName", value = "用户名", dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "registerTimeStart", value = "开始时间", dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "registerTimeEnd", value = "结束时间", dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "order", value = "排序json", dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "page", value = "页码", dataType = "String", paramType = "query"),
        @ApiImplicitParam(name = "size", value = "每页显示的条数", dataType = "String", paramType = "query", defaultValue = "10")
    })
    @PostMapping(value = "/list", name = "UserInfo列表信息")
    public Result list(
            @RequestParam(required = false) String userId,
            @RequestParam(required = false) String phoneNumber,
            @RequestParam(required = false) String examine,
            @RequestParam(required = false) String fullName,
            @RequestParam(required = false) String registerTimeStart,
            @RequestParam(required = false) String registerTimeEnd,
            @RequestParam(required = false) String userType,
            @RequestParam(defaultValue = "{}") String order,
            @RequestParam(defaultValue = "0") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {

        Map<String, Object> params = new HashMap<>();
        params.put("userId",userId);
        params.put("phoneNumber",phoneNumber);
        params.put("examine",examine);
        params.put("fullName",fullName);
        params.put("registerTimeStart",registerTimeStart);
        params.put("registerTimeEnd",registerTimeEnd);
        params.put("type", IdentificationStatusEnums.USER_PLAYER);
        params.put("userType",userType);
        return userInfoService.list(params, order, page, size);
    }


    @PostMapping(value = "/export", name = "导出用户")
    public void export(
            @RequestParam(required = false) String userId,
            @RequestParam(required = false) String phoneNumber,
            @RequestParam(required = false) String examine,
            @RequestParam(required = false) String fullName,
            @RequestParam(required = false) String registerTimeStart,
            @RequestParam(required = false) String registerTimeEnd,
            @RequestParam(required = false) String userType,
            HttpServletResponse response) throws IOException {

        Map<String, Object> params = new HashMap<>();
        params.put("userId",userId);
        params.put("phoneNumber",phoneNumber);
        params.put("examine",examine);
        params.put("fullName",fullName);
        params.put("registerTimeStart",registerTimeStart);
        params.put("registerTimeEnd",registerTimeEnd);
        params.put("type", IdentificationStatusEnums.USER_PLAYER);
        params.put("userType",userType);
        List<Map<String, Object>> res =userInfoService.listExport(params);
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet("用户信息");
        // 设置要导出的文件的名字
        String fileName = "mmc_users"  + new Date() + ".xls";
        // 新增数据行，并且设置单元格数据
        int rowNum = 1;

        String[] headers = { "ID","User Name", "Email Address", "Phone Number", "Way to Register","Member Level"};
        HSSFRow row = sheet.createRow(0);
        for(int i=0;i<headers.length;i++){
            HSSFCell cell = row.createCell(i);
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);
            cell.setCellValue(text);
        }
        //在表中存放查询到的数据放入对应的列
        for (Map<String, Object> item : res) {
            HSSFRow row1 = sheet.createRow(rowNum);
            row1.createCell(0).setCellValue(getValue(item.get("userId")));
            row1.createCell(1).setCellValue(getValue(item.get("fullName")));
            row1.createCell(2).setCellValue( getValue(item.get("email")));
            row1.createCell(3).setCellValue(getValue(item.get("phoneNumber")));
            row1.createCell(4).setCellValue(getValue(item.get("registerType")));
            row1.createCell(5).setCellValue(getValue(item.get("vipLevel")));
            rowNum++;
        }

        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        response.flushBuffer();
        workbook.write(response.getOutputStream());

    }

    private String getValue(Object value){
        return value!=null ?value.toString() : "";
    }
    @ApiOperation(value = "用户审核", tags = {"UserInfo"}, notes = "用户审核")
    @PostMapping(value="/examine",name="用户审核")
    public Result examine(@ApiParam UserExamineLog userExamineLog, Authentication authentication) {
        Long userId = getAuthUser(authentication).getId();
        userExamineLog.setUserId(userId);
        return userInfoService.examine(userExamineLog);
    }

    @ApiOperation(value = "用户升级为promax", tags = {"UserInfo"}, notes = "用户升级为promax")
    @PostMapping(value="/pro/max",name="用户审核")
    public Result examine(Long userId) {
        UserInfo info = userInfoService.findById(userId);
        info.setVipLevel(IdentificationStatusEnums.USER_LEVEL_PRO);
        info.setVipExpireTime(new Date().getTime());
        userInfoService.update(info);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "发送忘记密码", tags = {"User"}, notes = "发送忘记密码")
    @PostMapping(value="/forget/password",name="发送忘记密码")
    public Result forgetPassword(@RequestParam String email) {
        return userInfoService.forgetPassword(email);
    }

    @ApiOperation(value = "修改忘记密码", tags = {"User"}, notes = "修改忘记密码")
    @PostMapping(value="/forget/update",name="发送忘记密码")
    public Result forgetPasswordUpdate(@RequestParam String password,Authentication authentication) {
         AuthUser authUser =  getAuthUser(authentication);
        return userInfoService.forgetPasswordUpdate(password,authUser.getId());
    }


    @ApiOperation(value = "订阅", tags = {"User"}, notes = "订阅")
    @PostMapping(value="/subscribe",name="订阅")
    public Result subscribe(Integer id,Authentication authentication ) {
        SubscribeVo subscribeVo = subscribeList.getSubscribeVos().stream().filter(vo -> vo.getId()==id).findFirst().orElse(null);
        return userInfoService.subscribe(subscribeVo,getAuthUser(authentication).getId());
    }

    @ApiOperation(value = "订阅计划", tags = {"User"}, notes = "订阅计划")
    @PostMapping(value="/subscribe/list",name="订阅计划")
    public Result subscribe() {
        return ResultGenerator.genSuccessResult(subscribeList);
    }


    @ApiOperation(value = "订阅计划", tags = {"User"}, notes = "订阅计划")
    @PostMapping(value="/mark",name="订阅计划")
    public Result mark(Authentication authentication) {
        return userInfoService.mark(getAuthUser(authentication).getId());
    }
}
